package com.easepal7506a.project.ui.presenter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.ogawa.base.Constant.Constants;
import com.easepal7506a.project.R;
import com.easepal7506a.project.manager.DataManager;
import com.easepal7506a.project.observer.SoftApOldModel;
import com.easepal7506a.project.ui.iview.ISoftApOldView;
import com.example.reslib.utils.PreferenceWrapper;
import com.example.reslib.utils.ToastUtils;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

import static com.easepal7506a.project.observer.SoftApOldModel.ACTION_SUCCESS;
import static com.easepal7506a.project.observer.SoftApOldModel.CONNECT_DEVICE_TIMEOUT;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_RESULT_NULL;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_SOCKET_FAILED;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_SOCKET_NULL;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_SSID_NULL;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_WIFI_DISABLED;
import static com.easepal7506a.project.observer.SoftApOldModel.ERROR_WIFI_FAILED;
import static com.easepal7506a.project.observer.SoftApOldModel.READ_SN_TIMEOUT;
import static com.easepal7506a.project.observer.SoftApOldModel.SCAN_AP_TIMEOUT;
import static com.easepal7506a.project.observer.SoftApOldModel.VIEW_DEVICE;
import static com.easepal7506a.project.observer.SoftApOldModel.VIEW_WIFI;

/**
 * 作者: bright.lin@medisana.net.cn
 * 时间: 2018/12/19
 * 标题: 配网Presenter层
 * 描述: 配网功能Presenter层实现
 * 修改: 由 bright.lin@medisana.net.cn 修改于 2018/12/28
 */
public class SoftApOldPresenter {
    private final static String TAG = /*SoftApPresenter.class.getName()*/"TEST";

    // View层对象
    private ISoftApOldView mView;
    // Model层对象
    private SoftApOldModel softApModel;

    // 页面类型
    private int viewType;
    // 是否配网成功标志位
    private boolean isSuccess = false;

    private boolean isAutoLink;

    private int mChoose;

    private static final int SCAN_WIFI_FAIL = 1;
    private static final int RESCAN_WIFI = 2;
    private static final int SCAN_WIFI_TIME_OUT = 20000;
    private boolean firstScan = true;

    private Context mContext;

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case SCAN_WIFI_FAIL:
                    isAutoLink = false;
                    handler.removeMessages(RESCAN_WIFI);
//                    mView.dismissWaiting();
//                    handleConnectDeviceFailue(0);
                    confirm("");
                    break;
                case RESCAN_WIFI:
                    scan();
                    break;
            }
        }
    };

    /**
     * 带参构造器
     *
     * @param context 上下文
     * @param view    View层对象
     */
    public SoftApOldPresenter(Context context, ISoftApOldView view) {
        this.mView = view;
        mContext = context;
        softApModel = new SoftApOldModel(context);
    }

    /**
     * 释放资源
     */
    public void onDestroy() {
        softApModel.onDestroy();
    }

    /**
     * 初始化
     */
    public void init() {
        PreferenceWrapper mSp = new PreferenceWrapper();
        mChoose = Integer.parseInt(mSp.getStringValue("app", "1"));
        viewType = VIEW_DEVICE;
        isAutoLink = true;
        if (mChoose != 4) {
            scan();
        }
    }

    /**
     * 刷新WIFI按钮响应
     */
    public void scan() {
        mView.showWaiting();
        if (mChoose == 4 && viewType == VIEW_DEVICE && firstScan) {
            handler.sendEmptyMessageDelayed(SCAN_WIFI_FAIL, SCAN_WIFI_TIME_OUT);
        }
        Observable.create(this::startScan)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    Disposable d;

                    @Override
                    public void onSubscribe(Disposable d) {
                        this.d = d;
                    }

                    @Override
                    public void onNext(Integer integer) {
                        switch (integer) {
                            case VIEW_DEVICE:
                                if (mChoose == 4 && isAutoLink) {
                                    for (ScanResult deviceResult : softApModel.getScanResults()) {
                                        if (Constants.AUTO_LINK_SSID.equals(deviceResult.SSID)) {
                                            handler.removeMessages(SCAN_WIFI_FAIL);
                                            isAutoLink = false;
                                            confirm("");
                                            break;
                                        }
                                    }
                                    if (isAutoLink) {
                                        firstScan = false;
                                        handler.sendEmptyMessageDelayed(RESCAN_WIFI,1000);
                                    } else {
                                        firstScan = true;
                                    }
                                } else {
                                    mView.dismissWaiting();
                                }
                                mView.onWifiList(softApModel.getDeviceResults());
                                break;
                            case VIEW_WIFI:
                                mView.dismissWaiting();
                                mView.onWifiList(softApModel.getWifiResults());
                                break;
                            default:
                                mView.dismissWaiting();
                                handleScanFailue(integer);
                                break;
                        }
                        d.dispose();
                    }

                    @Override
                    public void onError(Throwable e) {
                        mView.dismissWaiting();
                        d.dispose();
                    }

                    @Override
                    public void onComplete() {
                        mView.dismissWaiting();
                        d.dispose();
                    }
                });
    }

    /**
     * 开始扫描WIFI
     *
     * @param emitter 事件发射器
     */
    private void startScan(ObservableEmitter<Integer> emitter) {
        softApModel.startScan(viewType, new SoftApOldModel.ScanApListener() {
            @Override
            public void onSuccess(int type) {
                emitter.onNext(type);
                Log.d(TAG, "startScan emitter onSuccess");
            }

            @Override
            public void onFailure(int errorCode) {
                emitter.onNext(errorCode);
                Log.d(TAG, "startScan emitter onFailure");
            }
        });
        Log.d(TAG, "startScan");
    }

    /**
     * 确认按钮响应
     *
     * @param psw 密码
     */
    public void confirm(String psw) {
        Log.d(TAG, "confirm:" + viewType + " psw:" + psw);
        Observable<Integer> confirmObservable;
        switch (viewType) {
            case VIEW_DEVICE:
                confirmObservable = Observable.create(this::connectDevice);
                break;
            case VIEW_WIFI:
                if (psw != null && (psw.length() != 0 && (psw.length() < 8 || psw.length() > 32))) {
                    ToastUtils.showShortToast(mContext.getApplicationContext(), mContext.getString(R.string.wifi_psw_error));
                    return;
                }
                softApModel.setWifiPassword(psw);
                confirmObservable = Observable.create(this::getSn);
                break;
            default:
                confirmObservable = null;
                break;
        }
        if (null == confirmObservable) return;
        mView.showWaiting();
        confirmObservable.observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    Disposable d;

                    @Override
                    public void onSubscribe(Disposable d) {
                        this.d = d;
                    }

                    @Override
                    public void onNext(Integer integer) {
                        mView.dismissWaiting();
                        switch (integer) {
                            case ACTION_SUCCESS:
                                handleSuccess();
                                break;
                            default:
                                if (viewType == VIEW_DEVICE) {
                                    handleConnectDeviceFailue(integer);
                                } else {
                                    handleGetSnFailue(integer);
                                }
                                break;
                        }
                        d.dispose();
                    }

                    @Override
                    public void onError(Throwable e) {
                        mView.dismissWaiting();
                        d.dispose();
                    }

                    @Override
                    public void onComplete() {
                        mView.dismissWaiting();
                        d.dispose();
                    }
                });
    }

    /**
     * 连接设备热点
     *
     * @param emitter 事件发射器
     */
    private void connectDevice(ObservableEmitter<Integer> emitter) {
        softApModel.connectDevice(new SoftApOldModel.ConnectApListener() {
            @Override
            public void onSuccess() {
                emitter.onNext(ACTION_SUCCESS);
            }

            @Override
            public void onFailure(int errorCode) {
                Log.d(TAG, "connectDevice->onFailure:" + errorCode);
                emitter.onNext(errorCode);
            }
        });
    }

    /**
     * 读取Sn码
     *
     * @param emitter 事件发射器
     */
    private void getSn(ObservableEmitter<Integer> emitter) {
        softApModel.getSn(new SoftApOldModel.ReadSnListener() {
            @Override
            public void onSuccess() {
                emitter.onNext(ACTION_SUCCESS);
            }

            @Override
            public void onFailure(int errorCode) {
                Log.d(TAG, "getSn->onFailure:" + errorCode);
                emitter.onNext(errorCode);
            }
        });
    }

    /**
     * 处理成功事件
     */
    public void handleSuccess() {
        if (viewType == VIEW_DEVICE) {
            mView.showDialog(R.string.softap_tip1_dialog_success_wifi, R.string.softap_tip2_dialog_success_wifi);
            mView.onConnectWifi(softApModel.getWifiSsid(), softApModel.getWifiPsw());
            viewType = VIEW_WIFI;
            mView.onWifiList(softApModel.getWifiResults());
        } else {
            DataManager.getInst().setConnectSocket(false);
            mView.showDialog(R.string.softap_tip1_dialog_success_all, R.string.softap_tip2_dialog_success_all);
            isSuccess = true;
        }
    }

    /**
     * 设置ScanResult
     *
     * @param scanResult ScanResult对象
     */
    public void setScanResult(ScanResult scanResult) {
        switch (viewType) {
            case VIEW_DEVICE:
                softApModel.setDeviceScanResult(scanResult);
                break;
            case VIEW_WIFI:
                softApModel.setWifiScanResult(scanResult);
                break;
        }
    }

    /**
     * 检查是否配网成功
     */
    public void checkSuccess() {
        if (isSuccess) {
            mView.onFinish();
        }
    }

    /**
     * 处理扫描失败事件
     *
     * @param errorCode 错误码
     */
    private void handleScanFailue(int errorCode) {
        switch (errorCode) {
            case SCAN_AP_TIMEOUT:
                Log.d(TAG, "handleScanFailue:time out");
                break;
            case ERROR_WIFI_DISABLED:
                mView.showDialog(R.string.softap_tip1_dialog_failure_scan, R.string.softap_tip2_dialog_failure_scan);
                break;
        }
    }

    /**
     * 处理连接设备热点失败事件
     *
     * @param errorCode 错误码
     */
    private void handleConnectDeviceFailue(int errorCode) {
        Log.d(TAG, "handleConnectDeviceFailure:" + errorCode);
        if (mChoose == 4) {
            mView.showDialog(R.string.softap_tip_heat_connect_failure, R.string.softap_tip1_heat_connect_failure);
        } else {
            switch (errorCode) {
                case ERROR_RESULT_NULL:
                case ERROR_WIFI_FAILED:
                case CONNECT_DEVICE_TIMEOUT:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_wifi, R.string.softap_tip2_dialog_failure_wifi);
                    break;
                case ERROR_WIFI_DISABLED:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_wifi, R.string.softap_tip2_dialog_failure_scan);
                    break;
                case ERROR_SSID_NULL:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_wifi, R.string.softap_tip3_dialog_failure_wifi);
                    break;
            }
        }
        mView.onWifiList(softApModel.getDeviceResults());
    }

    /**
     * 处理读取Sn码失败事件
     *
     * @param errorCode 错误码
     */
    private void handleGetSnFailue(int errorCode) {
        Log.d(TAG, "handleGetSnFailue:" + errorCode);
        if (mChoose == 4) {
            mView.showDialog(R.string.softap_tip1_dialog_failure_all, R.string.softap_tip5_reopen_wifi_heat);
            onConnectDevice();
        } else {
            switch (errorCode) {
                case ERROR_SOCKET_NULL:
                case ERROR_SOCKET_FAILED:
                case ERROR_WIFI_FAILED:
                case READ_SN_TIMEOUT:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_all, R.string.softap_tip2_dialog_failure_all);
                    onConnectDevice();
                    break;
                case ERROR_SSID_NULL:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_all, R.string.softap_tip3_dialog_failure_all);
                    onConnectWifi();
                    break;
                case ERROR_RESULT_NULL:
                case ERROR_WIFI_DISABLED:
                    mView.showDialog(R.string.softap_tip1_dialog_failure_all, R.string.softap_tip2_dialog_failure_scan);
                    onConnectWifi();
                    break;
            }
        }
    }

    /**
     * 更新为连接设备页面
     */
    private void onConnectDevice() {
        mView.onConnectDevice(softApModel.getDeviceSsid());
        viewType = VIEW_DEVICE;
        mView.onWifiList(softApModel.getDeviceResults());
    }

    /**
     * 更新为连接WIFI页面
     */
    private void onConnectWifi() {
        mView.onConnectWifi(softApModel.getWifiSsid(), softApModel.getWifiPsw());
        viewType = VIEW_WIFI;
        mView.onWifiList(softApModel.getWifiResults());
    }
}
